//
// Created by jiang on 2022/1/1.
//

#ifndef FOC_PARAM_H
#define FOC_PARAM_H

#include "main.h"

#if !defined(M_PI)
#define M_PI    (32768)
#endif




#define USE_CURR_AB
#if !defined(USE_CURR_AB) && !defined(USE_CURR_BC) && !defined(USE_CURR_ACC)
#define USE_CURR_AB
#endif



#define IIR_NL (5)
#define USE_CURR_FILTER_IIR
#if !defined(USE_CURR_FILTER_LPF) && !defined(USE_CURR_FILTER_KALMAN) && !defined(USE_CURR_FILTER_IIR)
#define USE_CURR_FILTER_LPF
#endif


#define USE_OUT_FILTER_KALMAN
#if !defined(USE_OUT_FILTER_LPF) && !defined(USE_OUT_FILTER_KALMAN) && !defined(USE_OUT_FILTER_IIR)
#define USE_OUT_FILTER_LPF
#endif

#define MOTO_POLE_COUNT         (4)

#define PWM_PERIOD_COUNT        (2999)
#define PWM_HALF_PERIOD_COUNT   ((PWM_PERIOD_COUNT)/(2))

#define PWM_FREQ                (8000)


typedef struct {
    int a;
    int b;
    int c;
} abc_t;

typedef struct {
    int alpha;
    int beta;
} ap_t;

typedef struct {
    int d;
    int q;
} dq_t;

// 一维滤波器信息结构体
typedef  struct{
    int Kg;   				    //Kalamn增益
    int A;   					// x(n)=A*x(n-1)+u(n),u(n)~N(0,Q)
    int H;   					// z(n)=H*x(n)+w(n),w(n)~N(0,R)
    int P;   					//估计误差协方差
    int Q;   					//预测过程噪声偏差的方差
    int R;   					//测量噪声偏差，(系统搭建好以后，通过测量统计实验获得)
}kalman_t;


typedef  struct{
    int result;
    int16_t nume[IIR_NL]; //分子
    int16_t deno[IIR_NL]; //分母
    int inBuff[IIR_NL];
    int outBuf[IIR_NL];
}iir_t;

typedef  struct{
    float result;
    float nume[IIR_NL]; //分子
    float deno[IIR_NL]; //分母
    float inBuff[IIR_NL];
    float outBuf[IIR_NL];
}iirf_t;

typedef  struct{
    uint16_t gain;
}lpf_t;

typedef  struct{
    uint8_t num;
    uint8_t index;
    uint8_t full;
    int old;
    int *array;
    int sum;
}mean_t;


typedef  struct{
    uint8_t num;
    uint8_t index;
    uint8_t full;
    int *src;
    int *dest;
}mid_t;


typedef struct {
    uint16_t adcValue[4];
} adc_t;

typedef struct {
    uint16_t iGain;
    uint16_t vGain;
    uint16_t current;
    uint16_t voltage;
    uint16_t maxVoltage;
    uint16_t minVoltage;
    uint16_t maxCurrent;
} bus_t;

typedef struct {
    uint16_t gain;
    abc_t calib;
    abc_t phase;
    abc_t filter;
#if defined(USE_CURR_AB) /**************************/

#if defined(USE_CURR_FILTER_LPF)
    lpf_t lpfa;
    lpf_t lpfb;
#elif defined(USE_CURR_FILTER_KALMAN)
    kalman_t klma;
    kalman_t klmb;

#elif defined(USE_CURR_FILTER_IIR)
    iir_t irra;
    iir_t irrb;
#endif

#elif defined(USE_CURR_BC) /**************************/

#if defined(USE_CURR_FILTER_LPF)
    lpf_t lpfb;
    lpf_t lpfc;
#elif defined(USE_CURR_FILTER_KALMAN)
    kalman_t klmb;
    kalman_t klmc;
#elif defined(USE_CURR_FILTER_IIR)
    iir_t irrb;
    iir_t irrc;
#endif

#elif defined(USE_CURR_AC) /**************************/

#if defined(USE_CURR_FILTER_LPF)
    lpf_t lpfa;
    lpf_t lpfc;
#elif defined(USE_CURR_FILTER_KALMAN)
    kalman_t klma;
    kalman_t klmc;
#elif defined(USE_CURR_FILTER_IIR)
    iir_t irra;
    iir_t irrc;
#endif

#endif


} curr_t;

typedef struct {
    uint16_t cmpVal[4];
} pwm_t;

typedef struct {
    uint8_t Hz500: 1;
    uint8_t Hz200: 1;
    uint8_t Hz100: 1;
    uint8_t Hz50: 1;
    uint8_t Hz20: 1;
    uint8_t Hz10: 1;
    uint8_t Hz5: 1;
    uint8_t Hz1: 1;

    uint8_t ms2;
    uint8_t ms5;
    uint8_t ms10;
    uint8_t ms20;
    uint8_t ms50;
    uint8_t ms100;
    uint8_t ms200;
    uint16_t ms1000;
} scheduler_t;


typedef struct {
    uint8_t enI;

    uint16_t Kp;
    uint16_t Ki;

    int32_t pOut;

    int32_t integral;
    int32_t iOut;
    int32_t iLimit;

    int32_t out;
    int32_t outLimit;
} pid_t;

typedef union {
    uint16_t all;
    struct {
        uint8_t drv_fault: 1;
        uint8_t ADC_error: 1;
        uint8_t : 1;
        uint8_t : 1;
        uint8_t hall_state_error: 1;
        uint8_t commutation_error: 1;
        uint8_t following_error: 1;
        uint8_t : 1;
        uint8_t voltage_low: 1;
        uint8_t voltage_high: 1;
        uint8_t over_temperature: 1;
        uint8_t over_current: 1;
        uint8_t : 1;
        uint8_t : 1;
        uint8_t : 1;
        uint8_t : 1;
    } bits;
} ERR_State_t;

typedef struct {
    int8_t dir;
    uint8_t enable;
    uint8_t ready;
    uint8_t sector;


    uint16_t theta;
    int16_t eSpeed;
    int16_t setRpm;

    ap_t ap_curr;
    dq_t dq_curr;

    mean_t meanId;
    mean_t meanIq;

    dq_t dq_fcur;

    dq_t dq_dest;
    dq_t dq_err;
    dq_t dq_out;

#if defined(USE_OUT_FILTER_LPF)
    lpf_t lpfd;
    lpf_t lpfq;

#elif defined(USE_OUT_FILTER_KALMAN)
    kalman_t klmd;
    kalman_t klmq;

#elif defined(USE_OUT_FILTER_IIR)
    iir_t irrd;
    iir_t irrq;

#endif

    dq_t dq_filter;
    ap_t ap_volt;
    abc_t t_phase;
} motor_t;


extern adc_t adc;
extern bus_t bus;
extern curr_t current;
extern pwm_t pwm;
extern scheduler_t scheduler;
extern motor_t motor;
extern ERR_State_t ERR_State;
extern pid_t Idpi;
extern pid_t Iqpi;



#endif //FOC_PARAM_H
